package com.zycfc.zsf.boot.util.text;

import java.text.*;
import com.zycfc.zsf.boot.util.time.*;
import java.util.*;
import org.slf4j.*;

public class IdCardUtils
{
    private static final Logger log;
    public static final int CHINA_ID_MIN_LENGTH = 15;
    public static final int CHINA_ID_MAX_LENGTH = 18;
    public static final String[] cityCode;
    public static final int[] power;
    public static final String[] verifyCode;
    public static final int MIN = 1930;
    private static final String ID_CARD_IS_EMPTY = "\u8eab\u4efd\u8bc1\u53f7\u4e0d\u80fd\u4e3a\u7a7a\uff01";
    private static final String ILLEGAL_ID_CARD = "\u975e\u6cd5\u7684\u8eab\u4efd\u8bc1\u53f7\uff1a";
    private static final String ILLEGAL_ID_CARD_AFTER_THAN_NOW = "\u975e\u6cd5\u7684\u8eab\u4efd\u8bc1\u53f7\uff0c\u5927\u4e8e\u5f53\u524d\u65e5\u671f\uff1a";
    private static final Map<String, Integer> twFirstCode;
    private static final Map<String, Integer> hkFirstCode;
    private static Map<String, String> identityNoList;
    
    public static String conver15CardTo18(final String idCard) {
        String idCard2 = "";
        if (idCard.length() != 15) {
            return null;
        }
        if (isNum(idCard)) {
            final String birthday = idCard.substring(6, 12);
            Date birthDate = null;
            try {
                birthDate = new SimpleDateFormat("yyMMdd").parse(birthday);
            }
            catch (ParseException e) {
                IdCardUtils.log.error(e.getMessage(), (Throwable)e);
            }
            final Calendar cal = Calendar.getInstance();
            if (birthDate != null) {
                cal.setTime(birthDate);
            }
            final String sYear = String.valueOf(cal.get(1));
            idCard2 = idCard.substring(0, 6) + sYear + idCard.substring(8);
            final char[] cArr = idCard2.toCharArray();
            if (cArr != null) {
                final int[] iCard = converCharToInt(cArr);
                final int iSum17 = getPowerSum(iCard);
                final String sVal = getCheckCode18(iSum17);
                if (sVal.length() <= 0) {
                    return null;
                }
                idCard2 += sVal;
            }
            return idCard2;
        }
        return null;
    }
    
    public static boolean validateCard(final String idCard) {
        final String card = idCard.trim();
        if (validateIdCard18(card)) {
            return true;
        }
        final String[] cardval = validateIdCard10(card);
        return cardval != null && cardval[2].equals("true");
    }
    
    public static boolean validateIdCard18(final String idCard) {
        boolean bTrue = false;
        if (idCard.length() != 18) {
            return bTrue;
        }
        if (!validArea(idCard)) {
            return false;
        }
        if (!validBirthDay(idCard)) {
            return false;
        }
        final String code17 = idCard.substring(0, 17);
        final String code18 = idCard.substring(17, 18);
        if (isNum(code17)) {
            final char[] cArr = code17.toCharArray();
            if (cArr != null) {
                final int[] iCard = converCharToInt(cArr);
                final int iSum17 = getPowerSum(iCard);
                final String val = getCheckCode18(iSum17);
                if (val.length() > 0 && val.equalsIgnoreCase(code18)) {
                    bTrue = true;
                }
            }
        }
        return bTrue;
    }
    
    public static boolean validateIdCard15(final String idCard) {
        if (idCard.length() != 15) {
            return false;
        }
        if (!validArea(idCard)) {
            return false;
        }
        if (!validBirthDay(idCard)) {
            return false;
        }
        if (isNum(idCard)) {
            final String birthCode = idCard.substring(6, 12);
            Date birthDate = null;
            try {
                birthDate = new SimpleDateFormat("yy").parse(birthCode.substring(0, 2));
            }
            catch (ParseException e) {
                IdCardUtils.log.error(e.getMessage(), (Throwable)e);
            }
            final Calendar cal = Calendar.getInstance();
            if (birthDate != null) {
                cal.setTime(birthDate);
            }
            return valiDate(cal.get(1), Integer.valueOf(birthCode.substring(2, 4)), Integer.valueOf(birthCode.substring(4, 6)));
        }
        return false;
    }
    
    public static String[] validateIdCard10(final String idCard) {
        final String[] info = new String[3];
        final String card = idCard.replaceAll("[\\(|\\)]", "");
        if (card.length() != 8 && card.length() != 9 && idCard.length() != 10) {
            return null;
        }
        if (idCard.matches("^[a-zA-Z][0-9]{9}$")) {
            info[0] = "\u53f0\u6e7e";
            System.out.println("11111");
            final String char2 = idCard.substring(1, 2);
            if (char2.equals("1")) {
                info[1] = "M";
                System.out.println("MMMMMMM");
            }
            else {
                if (!char2.equals("2")) {
                    info[1] = "N";
                    info[2] = "false";
                    System.out.println("NNNN");
                    return info;
                }
                info[1] = "F";
                System.out.println("FFFFFFF");
            }
            info[2] = (validateTWCard(idCard) ? "true" : "false");
        }
        else if (idCard.matches("^[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?$")) {
            info[0] = "\u6fb3\u95e8";
            info[1] = "N";
        }
        else {
            if (!idCard.matches("^[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?$")) {
                return null;
            }
            info[0] = "\u9999\u6e2f";
            info[1] = "N";
            info[2] = (validateHKCard(idCard) ? "true" : "false");
        }
        return info;
    }
    
    public static boolean validateTWCard(final String idCard) {
        final String start = idCard.substring(0, 1);
        final String mid = idCard.substring(1, 9);
        final String end = idCard.substring(9, 10);
        final Integer iStart = IdCardUtils.twFirstCode.get(start);
        Integer sum = iStart / 10 + iStart % 10 * 9;
        final char[] chars = mid.toCharArray();
        Integer iflag = 8;
        for (final char c : chars) {
            sum += Integer.valueOf(c + "") * iflag;
            --iflag;
        }
        return ((sum % 10 == 0) ? 0 : (10 - sum % 10)) == Integer.valueOf(end);
    }
    
    public static boolean validateHKCard(final String idCard) {
        String card = idCard.replaceAll("[\\(|\\)]", "");
        Integer sum = 0;
        if (card.length() == 9) {
            sum = (card.substring(0, 1).toUpperCase().toCharArray()[0] - 55) * 9 + (card.substring(1, 2).toUpperCase().toCharArray()[0] - 55) * 8;
            card = card.substring(1, 9);
        }
        else {
            sum = 522 + (card.substring(0, 1).toUpperCase().toCharArray()[0] - 55) * 8;
        }
        final String mid = card.substring(1, 7);
        final String end = card.substring(7, 8);
        final char[] chars = mid.toCharArray();
        Integer iflag = 7;
        for (final char c : chars) {
            sum += Integer.valueOf(c + "") * iflag;
            --iflag;
        }
        if (end.toUpperCase().equals("A")) {
            sum += 10;
        }
        else {
            sum += Integer.valueOf(end);
        }
        return sum % 11 == 0;
    }
    
    private static int[] converCharToInt(final char[] ca) {
        final int len = ca.length;
        final int[] iArr = new int[len];
        try {
            for (int i = 0; i < len; ++i) {
                iArr[i] = Integer.parseInt(String.valueOf(ca[i]));
            }
        }
        catch (NumberFormatException e) {
            IdCardUtils.log.error(e.getMessage(), (Throwable)e);
        }
        return iArr;
    }
    
    private static int getPowerSum(final int[] iArr) {
        int iSum = 0;
        if (IdCardUtils.power.length == iArr.length) {
            for (int i = 0; i < iArr.length; ++i) {
                for (int j = 0; j < IdCardUtils.power.length; ++j) {
                    if (i == j) {
                        iSum += iArr[i] * IdCardUtils.power[j];
                    }
                }
            }
        }
        return iSum;
    }
    
    private static String getCheckCode18(final int iSum) {
        String sCode = "";
        switch (iSum % 11) {
            case 10: {
                sCode = "2";
                break;
            }
            case 9: {
                sCode = "3";
                break;
            }
            case 8: {
                sCode = "4";
                break;
            }
            case 7: {
                sCode = "5";
                break;
            }
            case 6: {
                sCode = "6";
                break;
            }
            case 5: {
                sCode = "7";
                break;
            }
            case 4: {
                sCode = "8";
                break;
            }
            case 3: {
                sCode = "9";
                break;
            }
            case 2: {
                sCode = "x";
                break;
            }
            case 1: {
                sCode = "0";
                break;
            }
            case 0: {
                sCode = "1";
                break;
            }
        }
        return sCode;
    }
    
    public static int getAgeByIdCard(String idCard) {
        if (StringUtils.isEmpty(idCard)) {
            throw new IllegalArgumentException("\u8eab\u4efd\u8bc1\u53f7\u4e0d\u80fd\u4e3a\u7a7a\uff01");
        }
        final int iAge = 0;
        if (idCard.length() == 15) {
            final String tmp = conver15CardTo18(idCard);
            if (null != tmp && !tmp.isEmpty()) {
                idCard = tmp;
            }
        }
        Date bornDate = null;
        try {
            bornDate = DateUtils.FORMAT_NO_SEP_ON_DAY.parse(idCard.substring(6, 14));
        }
        catch (ParseException e) {
            throw new IllegalArgumentException("\u975e\u6cd5\u7684\u8eab\u4efd\u8bc1\u53f7\uff1a" + idCard);
        }
        final Calendar bornCal = Calendar.getInstance();
        bornCal.setTime(bornDate);
        final Calendar nowCal = Calendar.getInstance();
        if (bornCal.after(nowCal)) {
            throw new IllegalArgumentException("\u975e\u6cd5\u7684\u8eab\u4efd\u8bc1\u53f7\uff0c\u5927\u4e8e\u5f53\u524d\u65e5\u671f\uff1a" + idCard);
        }
        final int age = nowCal.get(1) - bornCal.get(1);
        return (nowCal.get(6) < bornCal.get(6)) ? (age - 1) : age;
    }
    
    public static String getBirthByIdCard(String idCard) {
        final Integer len = idCard.length();
        if (len < 15) {
            return null;
        }
        if (len == 15) {
            final String tmp = conver15CardTo18(idCard);
            if (null != tmp && !tmp.isEmpty()) {
                idCard = tmp;
            }
        }
        return idCard.substring(6, 14);
    }
    
    public static Short getYearByIdCard(String idCard) {
        final Integer len = idCard.length();
        if (len < 15) {
            return null;
        }
        if (len == 15) {
            final String tmp = conver15CardTo18(idCard);
            if (null != tmp && !tmp.isEmpty()) {
                idCard = tmp;
            }
        }
        return Short.valueOf(idCard.substring(6, 10));
    }
    
    public static Short getMonthByIdCard(String idCard) {
        final Integer len = idCard.length();
        if (len < 15) {
            return null;
        }
        if (len == 15) {
            final String tmp = conver15CardTo18(idCard);
            if (null != tmp && !tmp.isEmpty()) {
                idCard = tmp;
            }
        }
        return Short.valueOf(idCard.substring(10, 12));
    }
    
    public static Short getDateByIdCard(String idCard) {
        final Integer len = idCard.length();
        if (len < 15) {
            return null;
        }
        if (len == 15) {
            final String tmp = conver15CardTo18(idCard);
            if (null != tmp && !tmp.isEmpty()) {
                idCard = tmp;
            }
        }
        return Short.valueOf(idCard.substring(12, 14));
    }
    
    public static String getGenderByIdCard(String idCard) {
        String sGender = "N";
        if (idCard.length() == 15) {
            final String tmp = conver15CardTo18(idCard);
            if (null != tmp && !tmp.isEmpty()) {
                idCard = tmp;
            }
        }
        final String sCardNum = idCard.substring(16, 17);
        if (Integer.parseInt(sCardNum) % 2 != 0) {
            sGender = "M";
        }
        else {
            sGender = "F";
        }
        return sGender;
    }
    
    private static boolean isNum(final String val) {
        return val != null && !"".equals(val) && val.matches("^[0-9]*$");
    }
    
    private static boolean valiDate(final int iYear, final int iMonth, final int iDate) {
        final Calendar cal = Calendar.getInstance();
        final int year = cal.get(1);
        if (iYear < 1930 || iYear >= year) {
            return false;
        }
        if (iMonth < 1 || iMonth > 12) {
            return false;
        }
        int datePerMonth = 0;
        switch (iMonth) {
            case 4:
            case 6:
            case 9:
            case 11: {
                datePerMonth = 30;
                break;
            }
            case 2: {
                final boolean dm = ((iYear % 4 == 0 && iYear % 100 != 0) || iYear % 400 == 0) && iYear > 1930 && iYear < year;
                datePerMonth = (dm ? 29 : 28);
                break;
            }
            default: {
                datePerMonth = 31;
                break;
            }
        }
        return iDate >= 1 && iDate <= datePerMonth;
    }
    
    private static boolean validArea(final String idCard) {
        final String provinceid = idCard.substring(0, 2);
        for (final String id : IdCardUtils.cityCode) {
            if (id.equals(provinceid)) {
                return true;
            }
        }
        return false;
    }
    
    private static boolean validBirthDay(final String idCard) {
        Short year = null;
        Short month = null;
        Short day = null;
        try {
            year = getYearByIdCard(idCard);
            month = getMonthByIdCard(idCard);
            day = getDateByIdCard(idCard);
        }
        catch (NumberFormatException e) {
            IdCardUtils.log.info("\u8eab\u4efd\u8bc1\u5e74\u6708\u65e5\u8f6c\u6362\u6570\u5b57\u5931\u8d25");
            return false;
        }
        final boolean isRunYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
        if (month < 1 || month > 12) {
            return false;
        }
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
            if (day < 1 || day > 31) {
                return false;
            }
        }
        else if (month == 2) {
            if (isRunYear) {
                if (day < 1 || day > 29) {
                    return false;
                }
            }
            else if (day < 1 || day > 28) {
                return false;
            }
        }
        else if ((month == 4 || month == 6 || month == 9 || month == 11) && (day < 1 || day > 30)) {
            return false;
        }
        return true;
    }
    
    private static Map<String, String> loadIndetityNoList() {
        final Map<String, String> words = new HashMap<String, String>();
        final String path = "classpath:config/zsf/boot/util/identity.txt";
        ResourceLoaderUtils.load(new ResourceLoader() {
            @Override
            public void clear() {
            }
            
            @Override
            public void load(final List<String> lines) {
                for (final String str : lines) {
                    words.put(str, str);
                }
            }
        }, path);
        return words;
    }
    
    static {
        log = LoggerFactory.getLogger((Class)IdCardUtils.class);
        cityCode = new String[] { "11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71", "81", "82", "91" };
        power = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
        verifyCode = new String[] { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
        twFirstCode = new HashMap<String, Integer>();
        hkFirstCode = new HashMap<String, Integer>();
        IdCardUtils.identityNoList = null;
        IdCardUtils.identityNoList = loadIndetityNoList();
        IdCardUtils.twFirstCode.put("A", 10);
        IdCardUtils.twFirstCode.put("B", 11);
        IdCardUtils.twFirstCode.put("C", 12);
        IdCardUtils.twFirstCode.put("D", 13);
        IdCardUtils.twFirstCode.put("E", 14);
        IdCardUtils.twFirstCode.put("F", 15);
        IdCardUtils.twFirstCode.put("G", 16);
        IdCardUtils.twFirstCode.put("H", 17);
        IdCardUtils.twFirstCode.put("J", 18);
        IdCardUtils.twFirstCode.put("K", 19);
        IdCardUtils.twFirstCode.put("L", 20);
        IdCardUtils.twFirstCode.put("M", 21);
        IdCardUtils.twFirstCode.put("N", 22);
        IdCardUtils.twFirstCode.put("P", 23);
        IdCardUtils.twFirstCode.put("Q", 24);
        IdCardUtils.twFirstCode.put("R", 25);
        IdCardUtils.twFirstCode.put("S", 26);
        IdCardUtils.twFirstCode.put("T", 27);
        IdCardUtils.twFirstCode.put("U", 28);
        IdCardUtils.twFirstCode.put("V", 29);
        IdCardUtils.twFirstCode.put("X", 30);
        IdCardUtils.twFirstCode.put("Y", 31);
        IdCardUtils.twFirstCode.put("W", 32);
        IdCardUtils.twFirstCode.put("Z", 33);
        IdCardUtils.twFirstCode.put("I", 34);
        IdCardUtils.twFirstCode.put("O", 35);
        IdCardUtils.hkFirstCode.put("A", 1);
        IdCardUtils.hkFirstCode.put("B", 2);
        IdCardUtils.hkFirstCode.put("C", 3);
        IdCardUtils.hkFirstCode.put("R", 18);
        IdCardUtils.hkFirstCode.put("U", 21);
        IdCardUtils.hkFirstCode.put("Z", 26);
        IdCardUtils.hkFirstCode.put("X", 24);
        IdCardUtils.hkFirstCode.put("W", 23);
        IdCardUtils.hkFirstCode.put("O", 15);
        IdCardUtils.hkFirstCode.put("N", 14);
    }
}
